﻿using System;
using System.Net;
using System.IO;

namespace SharpStockLib.Net
{
    /// <summary>
    /// Basic class to download stuff from the Internetz.
    /// </summary>
    public class Downloader
    {
        /// <summary>
        /// Connects to the specified URL and downloads its contents to the specified file location.
        /// </summary>
        /// <param name="resourceToGet">Uri to the data to download.</param>
        /// <param name="outputPath">Path to where the contents of the above Uri must be store into. If the file already exists, it will be overwritten.</param>
        /// <returns>A DownloadResult structure telling what happened and what the results are.</returns>
        public static DownloadResult Download(Uri resourceToGet, string outputPath)
        {
            DownloadResult result = new DownloadResult();

            WebRequest req = WebRequest.Create(resourceToGet);

            // For corporate proxies and stuff, uses the current user's credentials to authenticate. If the credentials to the proxy differ from the Windows ones, we're screwed.
            if(req.Proxy != null)
                req.Proxy.Credentials = CredentialCache.DefaultCredentials;

            WebResponse resp = null;

            try
            {
                // Actually connects to the website and gets the data
                resp = req.GetResponse();
                Stream contents = resp.GetResponseStream();

                // Stores the data contained in the stream to a file
                if (contents != null && contents.CanRead)
                {
                    using (FileStream fs = new FileStream(outputPath, FileMode.Create))
                    {
                        contents.CopyTo(fs);
                        result.Status = DownloadStatus.NoError;
                        result.OutputFile = outputPath;
                    }
                }
            }
            catch (WebException we)
            {
                Console.WriteLine(we.Message);
                result.Status = DownloadStatus.ConnectionError;
                result.Exception = we;
            }
            catch (IOException ioe)
            {
                Console.WriteLine(ioe.Message);
                result.Status = DownloadStatus.FileCreationError;
                result.Exception = ioe;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                result.Status = DownloadStatus.UnexpectedError;
                result.Exception = e;
            }
            finally
            {
                // Better safe than sorry
                if (resp != null)
                    resp.Close();
            }


            return result;
        }
    }

    public enum DownloadStatus
    {
        NoError = 0,
        ConnectionError, // connection was fine but the website returned an error (file not found, etc...)
        FileCreationError, // file was downloaded but could not be saved in the output path (I/O errors, permissions, etc...)
        UnexpectedError // Any error that the code was not built to manage
    }
}
